package com.bootdo.order.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.bootdo.common.config.Constant;
import com.bootdo.common.utils.DateUtils;
import com.bootdo.common.utils.StringUtils;
import com.bootdo.cash.dao.CashDao;
import com.bootdo.essential.dao.BankDao;
import com.bootdo.merchant.dao.MerchantDao;
import com.bootdo.merchant.domain.MerchantDO;
import com.bootdo.mq.RabbitUtil;
import com.bootdo.mq.SendMessageToMQ;
import com.bootdo.order.task.LowerTask;
import com.bootdo.order.task.RequestTask;
import com.bootdo.order.dao.OrderDao;
import com.bootdo.order.dao.OrderPayDao;
import com.bootdo.order.dao.RecoverDao;
import com.bootdo.order.domain.OrderDO;
import com.bootdo.order.domain.OrderPayDO;
import com.bootdo.order.domain.RecoverDO;
import com.bootdo.order.service.OrderPayeeService;
import com.bootdo.payee.dao.PayeeAgentDao;
import com.bootdo.payee.dao.PayeeDao;
import com.bootdo.payee.dao.PaymentCodeDao;
import com.bootdo.payee.domain.PaymentCodeDO;
import com.bootdo.quota.dao.QuotaDao;
import com.bootdo.payee.domain.PayeeAgentDO;
import com.bootdo.payee.domain.PayeeDO;
import com.bootdo.quota.domain.QuotaDO;
import com.bootdo.system.dao.UserRoleDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

import static com.bootdo.common.utils.ShiroUtils.getUser;
import static com.bootdo.common.utils.ShiroUtils.getUserId;

/**
 * @Desc
 * @date 2019/12/10
 *
 */
@Service
public class OrderPayeeServiceImpl implements OrderPayeeService {

    @Autowired
    private OrderPayDao orderPayMapper;
    @Autowired
    private OrderDao orderMapper;
    @Autowired
    private QuotaDao quotaMapper;
    @Autowired
    private MerchantDao merchantMapper;
    @Autowired
    private PayeeDao payeeMapper;
    @Autowired
    private PayeeAgentDao payeeAgentMapper;
    @Autowired
    private CashDao cashMapper;
    @Autowired
    private BankDao bankMapper;
    @Autowired
    private RecoverDao recoverMapper;
    @Autowired
    private RabbitUtil rabbitUtil;
    @Autowired
    private PaymentCodeDao paymentCodeMapper;
    @Autowired
    private UserRoleDao userRoleMapper;

    @Override
    public List<PayeeDO> findPayee(Long userId){
        Map<String, Object> map = new HashMap<>();
        if (userId == null){
            //获取用户权限
            int checkUserIsManager = userRoleMapper.checkUserIsManager(getUserId());
            if (checkUserIsManager != 1){
                map.put("userIdCreate", getUserId());
            }
        } else {
            map.put("userIdCreate", userId);
        }
        return payeeMapper.list(map);
    }

    @Override
    public List<PayeeAgentDO> findAgent(){
        //获取用户权限
        int checkUserIsManager = userRoleMapper.checkUserIsManager(getUserId());
        if (checkUserIsManager != 1){
            return null;
        }
        return payeeAgentMapper.list(new HashMap<>());
    }

    /**
     * 获取订单收款户列表
     * @param map
     * @return
     */
    @Override
    public List<OrderPayDO> list(Map<String, Object> map){
        //格式话日期
        String startDate = (String) map.get("startTime");
        String endDate = (String) map.get("endTime");
        if (StringUtils.isNotBlank(startDate)){
            startDate = DateUtils.getDateOfFormat(startDate, DateUtils.DATE_TIME_PATTERN);
            endDate = DateUtils.getDateOfFormat(endDate, DateUtils.DATE_TIME_PATTERN);
            map.put("startTime", startDate);
            map.put("endTime", endDate);
        }
        //获取用户权限
        int checkUserIsManager = userRoleMapper.checkUserIsManager(getUserId());
        if (checkUserIsManager != 1){
            map.put("userId", getUserId());
        }
        return orderPayMapper.pList(map);
    }

    /**
     * 获取条数
     * @param map
     * @return
     */
    @Override
    public int count(Map<String, Object> map){
        return orderPayMapper.pConut(map);
    }

    /**
     * 补单
     * @param orderPay
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Exception.class)
    public int edit(OrderPayDO orderPay){
        orderPay = orderPayMapper.get(orderPay.getId());
        //根据订单获取二维码信息
        PaymentCodeDO paymentCode = paymentCodeMapper.queryCodeByUrl(orderPay.getPayeeCode());
        if (paymentCode != null){
            //根据当前二维码获取二维码空单最大位数
            Map<String, Object> map = new HashMap<>();
            map.put("payeeId", paymentCode.getUserIdCreate());
            map.put("payeeCode", orderPay.getPayeeCode());
            int sort = orderPayMapper.queryOrderMaxSort(map);
            //获取当前订单空单位数
            map.put("id", orderPay.getId());
            int sortO = orderPayMapper.queryOrderMaxSort(map);
            if (sort != sortO){
                paymentCodeMapper.updateEmptyCode(paymentCode.getCodeId(), paymentCode.getEmptyNumber()-1);
            } else {
                paymentCodeMapper.updateEmptyCode(paymentCode.getCodeId(), 0);
            }
        }
        if (2 == orderPay.getStatus().intValue()){
            return -2;
        }
        //更新订单状态为已付款
        orderPay.setStatus(2);
        int count = orderPayMapper.update(orderPay);
        OrderDO order = orderMapper.get(orderPay.getOrderId());
        order.setType(2);
        orderMapper.update(order);

        //验证是否订单超时
        boolean flag = false;
        if (!DateUtils.isOvertime(orderPay.getGmtCreate()) || 2 == order.getOvertimeStatus().intValue()){
            flag = true;
        }
        JSONObject object = new JSONObject();
        object.put("date", DateUtils.format(new Date(),DateUtils.DATE_TIME_PATTERN));
        object.put("orderId", orderPay.getOrderId());
        if(flag){
            //已超时恢复额度，需要扣除
            object.put("type", 2);
            object.put("money", orderPay.getOrderMoney());
            object.put("userId", orderPay.getPayeeId());
            object.put("reason", getUser().getUsername() + "超时补单");
            rabbitUtil.sendToQueue(Constant.UPDATE_QUOTA, object.toJSONString());
        }
        object.put("type", 1);
        object.put("money", orderPay.getPayeeMoney());
        object.put("userId", orderPay.getPayeeId());
        object.put("reason", "订单佣金，" + getUser().getUsername() + "补单");
        rabbitUtil.sendToQueue(Constant.UPDATE_QUOTA, object.toJSONString());

        QuotaDO quota = quotaMapper.get(orderPay.getPayeeAgentId());
        if (quota != null){
            if(flag){
                //已超时恢复额度，需要扣除
                object.put("type", 2);
                object.put("money", orderPay.getOrderMoney());
                object.put("userId", orderPay.getPayeeAgentId());
                object.put("reason", getUser().getUsername() + "超时补单");
                rabbitUtil.sendToQueue(Constant.UPDATE_QUOTA, object.toJSONString());
            }
            object.put("type", 1);
            object.put("money", orderPay.getPayeeMoney() + orderPay.getPayeeAgentMoney());
            object.put("userId", orderPay.getPayeeAgentId());
            object.put("reason", "订单佣金，" + getUser().getUsername() + "补单");
            rabbitUtil.sendToQueue(Constant.UPDATE_QUOTA, object.toJSONString());
        }

        //新增商户余额
        object.put("type", 1);
        object.put("money", orderPay.getOrderMoney());
        object.put("userId", orderPay.getMerchantId());
        object.put("reason", "订单支付（补单），" + getUser().getUsername() + "补单");
        rabbitUtil.sendToQueue(Constant.UPDATE_QUOTA, object.toJSONString());

        //扣除手续费
        object.put("type", 2);
        object.put("money", orderPay.getCountMoney());
        object.put("userId", orderPay.getMerchantId());
        object.put("reason", "订单手续费（补单），" + getUser().getUsername() + "补单");
        rabbitUtil.sendToQueue(Constant.UPDATE_QUOTA, object.toJSONString());

        //新增商户代理额度
        quota = quotaMapper.get(orderPay.getMerchantAgentId());
        if (quota != null && orderPay.getMerchantMoney() != null) {
            object.put("type", 1);
            object.put("money", orderPay.getMerchantMoney());
            object.put("userId", orderPay.getMerchantAgentId());
            object.put("reason", "订单支付（补单）," + getUser().getUsername() + "补单");
            rabbitUtil.sendToQueue(Constant.UPDATE_QUOTA, object.toJSONString());
        }

        //新增平台流水
        object.put("type", 1);
        object.put("money", orderPay.getPlatformMoney());
        object.put("userId", 2L);
        object.put("reason", "订单支付，" + getUser().getUsername() + "补单");
        rabbitUtil.sendToQueue(Constant.UPDATE_QUOTA, object.toJSONString());

        //补单成功后验证当前商户是否需要自动下发
        MerchantDO merchant = merchantMapper.get(orderPay.getMerchantId());
        if (merchant.getLower() != 0 && merchant.getLowerMoney() <= orderPay.getOrderMoney()){
            Constant.THREADPOOL.execute(new LowerTask(merchant, orderPay, bankMapper, quotaMapper, cashMapper));
        }
        //补单成功进行支付回调
        order = orderMapper.get(orderPay.getOrderId());
        String notifyUrl = order.getNotifyUrl();
        if (StringUtils.isNotBlank(notifyUrl)){
            Constant.THREADPOOL.execute(new RequestTask(merchant.getToken(), order, orderMapper));
        }

        return count;
    }

    /**
     * 追单申请
     * @param recover
     * @return
     */
    @Override
    public int recoverSave(RecoverDO recover){
        List<RecoverDO> list = recoverMapper.queryByOrderId(recover.getOrderId());
        if (list.size() <= 0){
            recover.setGmtCreate(new Date());
            recover.setUserId(getUserId());
            return recoverMapper.save(recover);
        }
        return 0;
    }

    @Override
    public OrderPayDO get(Long id) {
        return orderPayMapper.get(id);
    }
}
